
var TreeNode=function TreeNode(id, data,parent) {
	this.inheritToChild=false;
	this.isBranch = false;
	this.isOpened = false;
	this.nodeType = TreeNode.NODE_TYPE_LEAF;

	this.element = document.createElement("div");
	this.head = document.createElement("div");
	this.label = document.createElement("div");
	this.parent = parent;
	this.childNodes = [];	
	
	this.id = id;
	this.data = data;
	this.element.id = id;

	this.element.appendChild(this.head);
	this.element.appendChild(this.label);

	this.element.className = "TreeNode";
	this.head.className = "Head Leaf";
	this.label.className = "Label";

	this.head.innerHTML = "";
	this.label.innerHTML = data.label;
	
	this.expandMode=TreeNode.EXPAND_MODE_INTERACTION;

	this.onAttachToParent=null;
	this.onClickHandler=null;
	this.onHeadClickHandler=null;
	this.onExpandHandler=null;
	this.onCollapseHandler=null;
	this.onChildAddedHandler=null;
	
	
	this.head.addEventListener("click",Delegate.create(this,this._onHeadClick),false);
	this.label.addEventListener("click",Delegate.create(this,this._onClick),false);

	if (this.element != null)
		this.element.component = this;
	
	this.componentName = "TreeNode";
	if (parent != null){
		if(parent.className=="TreeNode")this.element,style.visibility="hidden";
		parent.appendChild(this.element);
		this.parent=parent;
		this._onAttachToParent();
	}
		
}.inherits(Component);

TreeNode.NODE_TYPE_LEAF = "LEAF";
TreeNode.NODE_TYPE_BRANCH = "BRANCH";
TreeNode.DEPTH_MARGIN = 20;


TreeNode.EXPAND_MODE_INTERACTION="INTERACTION";
TreeNode.EXPAND_MODE_COMMAND="COMMAND";

TreeNode.prototype.collapse = function() {
	var i,l;
	for ( i = 0,l=this.childNodes.length; i <l; i++) {
		this.childNodes[i].hide();
	}
	
	this.head.className=this.head.className.split(" Opened").join("");
	this._onCollapse();
	this.isOpened=false;
};

TreeNode.prototype.expand = function() {
	if(this.isOpened || !this.isBranch)return;
	
	var i,l;
	for ( i = 0,l=this.childNodes.length; i <l; i++) {
		this.childNodes[i].display();
	}
	
	this.head.className=this.head.className.split(" Opened").join("");
	this.head.className+=" Opened";	
	this._onExpand();
	this.isOpened=true;
};

TreeNode.prototype.collapseAll = function() {
	var i,l;
	for ( i = 0,l=this.childNodes.length; i <l; i++) {
		this.childNodes[i].collapseAll();
	}
	this.collapse();
};

TreeNode.prototype.expandAll = function() {
	var i,l;
	for ( i = 0,l=this.childNodes.length; i <l; i++) {
		this.childNodes[i].expandAll();
	}
	this.expand();
};

TreeNode.prototype.appendChild = function(child) {
	child.hide();
	child.parent=this;	
	this.childNodes.push(child);
	child._onAttachToParent(this);
	this._onChildAdded(child);
	
	if(this.inheritToChild){
		child.inheritToChild=this.inheritToChild;
		child.onAttachToParent=this.onAttachToParent;
		child.onClickHandler=this.onClickHandler;
		child.onHeadClickHandler=this.onHeadClickHandler;
		child.onExpandHandler=this.onExpandHandler;
		child.onCollapseHandler=this.onCollapseHandler;
		child.onChildAddedHandler=this.onChildAddedHandler;	
		child.setExpandMode(this.expandMode);
	}
	
	this.isBranch=true;
	
	this.head.className=this.head.className.split(" Leaf").join("");
	this.head.className=this.head.className.split(" Branch").join("");
	this.head.className+=" Branch";
		
	insertAfter(this.element,child.element);
};

TreeNode.prototype.attachTo = function(parent) {	
	this.parent = parent;
	this._onAttachToParent();
	parent.appendChild(this.element);
};

TreeNode.prototype._onChildAdded = function(child) {
	if(this.onChildAddedHandler!=null)
		this.onChildAddedHandler(child);
};

TreeNode.prototype._onExpand = function() {
	if(this.onExpandHandler!=null){
		this.onExpandHandler(this);
	}
};

TreeNode.prototype._onCollapse = function() {
	if(this.onCollapseHandler!=null){
		this.onCollapseHandler(this);
	}	
};

TreeNode.prototype._onClick = function() {
	if(this.onClickHandler!=null){
		event.node=this;
		this.onClickHandler(event);
	}	
};

TreeNode.prototype._onHeadClick = function() {
	if(this.isBranch && this.expandMode==TreeNode.EXPAND_MODE_INTERACTION){
		if(this.isOpened){
			this.collapse();
		}else{
			this.expand();
		}
	}
	
	if(this.onHeadClickHandler!=null){
		event.node=this;
		this.onHeadClickHandler(event);
	}
};

TreeNode.prototype._onAttachToParent = function() {	
	this.depth=(this.parent.depth!=undefined)?this.parent.depth+1:0;
	this.element.style.marginLeft=TreeNode.DEPTH_MARGIN*this.depth+"px";		
	if(this.onAttachToParent!=null)this.onAttachToParent(this);
};

TreeNode.prototype.setInheritToChild = function(flag) {
	this.inheritToChild=flag;
};

TreeNode.prototype.setOnClickHandler = function(handler) {
	this.onClickHandler=handler;
};

TreeNode.prototype.setOnAttachToParent=function(handler){
	this.onAttachToParent=handler;
}
;
TreeNode.prototype.setOnHeadClickHandler=function(handler){
	this.onHeadClickHandler=handler;
};

TreeNode.prototype.setOnChildAddedHandler=function(handler){
	this.onChildAddedHandler=handler;
};

TreeNode.prototype.setOnExpandHandler=function(handler){
	this.onExpandHandler=handler;
};

TreeNode.prototype.setOnCollapseHandler=function(handler){
	this.onCollapseHandler=handler;
};

TreeNode.prototype.setExpandMode=function(mode){
	this.expandMode=mode;
};

TreeNode.prototype.display=function(){
	this.element.style.display="block";
	if(this.isOpened){
		var i,l;
		for ( i = 0,l=this.childNodes.length; i <l; i++) {
			this.childNodes[i].display();
		}
	}		
};

TreeNode.prototype.hide=function(){
	this.element.style.display="none";
	var i,l;
	for ( i = 0,l=this.childNodes.length; i <l; i++) {
		this.childNodes[i].hide();
	}	
};

function insertAfter(referenceNode, newNode) {
	referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

